#include <iostream>

using std::cout;
using std::endl;

template<class T>
class ObjectPool{
  public:
    T *New(){
      size_t objSize = sizeof(T) > sizeof(void *) ? sizeof(T) : sizeof(void *);
      T *obj;

      if(_freeList){
        void *next = *(void**)_freeList;
        obj = (T *)_freeList;
        _freeList = next;

        new(obj) T;
        return obj;
      }

      if(_remainMem < objSize){
        _memory = (char *)malloc(128 * 1024); 
        _remainMem = 128 * 1024; 
        if(!_memory) {
          throw std::bad_alloc();
        }
      }

      obj = (T *)_memory;
      _remainMem -= objSize;
      _memory += objSize; 
      new(obj) T;
      return obj;
    }

    void Delete(T *obj){
      obj->~T();

      *(void**)obj = _freeList; 
      _freeList = obj;
    }

  private:
    char *_memory = nullptr;
    size_t _remainMem = 0;
    void *_freeList = nullptr;
};
